using System;
using System.ComponentModel;

namespace FileSyncApp
{
    /// <summary>
    /// 同步任务状态枚举
    /// </summary>
    public enum SyncTaskStatus
    {
        /// <summary>
        /// 等待中 - 任务已创建但尚未开始
        /// </summary>
        Pending,
        
        /// <summary>
        /// 运行中 - 任务正在执行同步操作
        /// </summary>
        Running,
        
        /// <summary>
        /// 已暂停 - 任务被用户暂停
        /// </summary>
        Paused,
        
        /// <summary>
        /// 已停止 - 任务被用户停止
        /// </summary>
        Stopped,
        
        /// <summary>
        /// 错误 - 任务执行过程中发生错误
        /// </summary>
        Error,
        
        /// <summary>
        /// 已完成 - 初始同步完成，正在监控中
        /// </summary>
        Completed
    }

    /// <summary>
    /// 同步任务优先级枚举
    /// </summary>
    public enum SyncTaskPriority
    {
        /// <summary>
        /// 低优先级
        /// </summary>
        Low = 1,
        
        /// <summary>
        /// 普通优先级
        /// </summary>
        Normal = 2,
        
        /// <summary>
        /// 高优先级
        /// </summary>
        High = 3,
        
        /// <summary>
        /// 紧急优先级
        /// </summary>
        Urgent = 4
    }

    /// <summary>
    /// 同步任务类，表示一个文件夹同步任务
    /// 包含任务的基本信息、状态和统计数据
    /// </summary>
    public class SyncTask : INotifyPropertyChanged
    {
        /// <summary>
        /// 属性更改事件
        /// </summary>
        public event PropertyChangedEventHandler? PropertyChanged;
        
        private SyncTaskStatus _status;
        private int _syncedFileCount;
        private int _totalFileCount;
        
        /// <summary>
        /// 任务唯一标识符
        /// </summary>
        public string Id { get; }
        
        /// <summary>
        /// 任务名称，用户自定义的任务描述
        /// </summary>
        public string Name { get; set; }
        
        /// <summary>
        /// 源文件夹路径
        /// </summary>
        public string SourcePath { get; }
        
        /// <summary>
        /// 目标文件夹路径
        /// </summary>
        public string TargetPath { get; }
        
        /// <summary>
        /// 任务当前状态
        /// </summary>
        public SyncTaskStatus Status 
        { 
            get => _status;
            set 
            {
                if (_status != value)
                {
                    _status = value;
                    OnPropertyChanged();
                }
            }
        }
        
        /// <summary>
        /// 任务优先级
        /// </summary>
        public SyncTaskPriority Priority { get; set; }
        
        /// <summary>
        /// 任务创建时间
        /// </summary>
        public DateTime CreatedAt { get; }
        
        /// <summary>
        /// 任务开始时间
        /// </summary>
        public DateTime? StartedAt { get; set; }
        
        /// <summary>
        /// 任务完成时间
        /// </summary>
        public DateTime? CompletedAt { get; set; }
        
        /// <summary>
        /// 最后错误信息
        /// </summary>
        public string? LastError { get; set; }
        
        /// <summary>
        /// 已同步文件数量
        /// </summary>
        public int SyncedFileCount 
        { 
            get => _syncedFileCount;
            set 
            {
                if (_syncedFileCount != value)
                {
                    _syncedFileCount = value;
                    OnPropertyChanged();
                    OnPropertyChanged(nameof(Progress));
                }
            }
        }
        
        /// <summary>
        /// 总文件数量
        /// </summary>
        public int TotalFileCount 
        { 
            get => _totalFileCount;
            set 
            {
                if (_totalFileCount != value)
                {
                    _totalFileCount = value;
                    OnPropertyChanged();
                    OnPropertyChanged(nameof(Progress));
                }
            }
        }
        
        /// <summary>
        /// 同步进度百分比 (0-100)
        /// </summary>
        public double Progress => TotalFileCount > 0 ? (double)SyncedFileCount / TotalFileCount * 100 : 0;
        
        /// <summary>
        /// 关联的FileSyncService实例
        /// </summary>
        public FileSyncService? SyncService { get; set; }

        /// <summary>
        /// 构造函数，创建新的同步任务
        /// </summary>
        /// <param name="name">任务名称</param>
        /// <param name="sourcePath">源文件夹路径</param>
        /// <param name="targetPath">目标文件夹路径</param>
        /// <param name="priority">任务优先级，默认为普通</param>
        public SyncTask(string name, string sourcePath, string targetPath, SyncTaskPriority priority = SyncTaskPriority.Normal)
        {
            Id = Guid.NewGuid().ToString();
            Name = name;
            SourcePath = sourcePath;
            TargetPath = targetPath;
            Priority = priority;
            Status = SyncTaskStatus.Pending;
            CreatedAt = DateTime.Now;
            SyncedFileCount = 0;
            TotalFileCount = 0;
        }

        /// <summary>
        /// 获取任务运行时长
        /// </summary>
        /// <returns>运行时长，如果任务未开始则返回TimeSpan.Zero</returns>
        public TimeSpan GetRunningTime()
        {
            if (StartedAt == null) return TimeSpan.Zero;
            
            DateTime endTime = CompletedAt ?? DateTime.Now;
            return endTime - StartedAt.Value;
        }

        /// <summary>
        /// 重置任务状态，用于重新启动任务
        /// </summary>
        public void Reset()
        {
            Status = SyncTaskStatus.Pending;
            StartedAt = null;
            CompletedAt = null;
            LastError = null;
            SyncedFileCount = 0;
            TotalFileCount = 0;
        }

        /// <summary>
        /// 获取任务的简要描述
        /// </summary>
        /// <returns>任务描述字符串</returns>
        public override string ToString()
        {
            return $"{Name} ({Status}) - {SourcePath} -> {TargetPath}";
        }
        
        /// <summary>
        /// 触发属性更改事件
        /// </summary>
        /// <param name="propertyName">属性名称</param>
        protected virtual void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string? propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}